package utl.mofen.handler;



import java.sql.SQLException;

import org.apache.log4j.Logger;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import utl.mofen.dbHandler.DBHandlerFactory;
import utl.mofen.dbHandler.IDBHandler;
import utl.mofen.intf.IDBOperator;
import utl.mofen.jsonStreamHandler.JSonStreamHandler;
import utl.mofen.objects.KeyStream;
import utl.mofen.objects.KeyStreamCoder;
import utl.mofen.script.SQLParser;
import utl.mofen.script.ScriptObjectFactory;
import utl.mofen.utils.StringUtil;

public class JSonStreamDBHandler extends JSonStreamHandler {
	private final Logger logger = Logger.getLogger(JSonStreamDBHandler.class);

	IDBOperator dbOperator = null;
	IDBOperator sysOperator = null;
	boolean withTrans = false;
	boolean isTrace = false;
	
	SQLParser sqlParser = null;
	JsonObject json = null;
	
	KeyStream keyStream = null;
	KeyStream resultKeyStream = null;
	
	private void beginTrans() throws SQLException
	{
		if (withTrans) dbOperator.beginTrans(getClass().getName());
	}
	
	private void commitTrans() throws SQLException
	{
		if (withTrans) dbOperator.commitTrans(getClass().getName());
	}	
    
	private void rollbackTrans() throws SQLException
	{
		if (withTrans) dbOperator.rollBack(getClass().getName());
	}
	
	protected void doDBAction() throws Exception
	{
		beginTrans();
		try
		{
			//执行子插件
			if (json.has("list"))
			{
				JsonArray upList = json.get("list").getAsJsonArray();
				try
				{
					for (int i = 0; i < upList.getAsJsonArray().size(); i++) 
					{
						JsonElement e = upList.get(i);
						try
						{
							if ((e!=null) && (!e.isJsonNull()) && (e.isJsonObject()))
							{
								try
								{
									IDBHandler dbHandler = DBHandlerFactory.createHandler(e.getAsJsonObject());
									dbHandler.setSession(this.getSession());
									dbHandler.setConfig(e.getAsJsonObject());
									dbHandler.setResultJSonStream(this.jsonStream);
									dbHandler.setDataKeyStream(keyStream);
									dbHandler.setResultKeyStream(resultKeyStream);
									dbHandler.setDBOperator(dbOperator);
									dbHandler.setSysOperator(sysOperator);
									dbHandler.setSQLParser(sqlParser);
									dbHandler.setIsTrace(isTrace);
									dbHandler.doAction();
								}catch (Exception exp)
								{
									logger.error("执行插件时出现了异常!\r\n" + exp.getMessage());
									throw exp;
								}	
								
							}
						}finally
						{
							e = null;
						}						
					}
				}finally
				{
					upList = null;
				}
			}
			commitTrans();
		}catch (Exception e)
		{
			this.rollbackTrans();
			throw e;
		}	
	}
	
	public void doAction() throws Exception 
	{
		try
		{
			DBHandlerFactory.checkInitialize(null);
			json = this.jsonStream.getJSonObject();		
			String key = JSonConfigReader.getdbid(json, "main");
			if (StringUtil.stringIsEmpty(key)) 
			{
				throw new Exception("没有指定主数据库id(config.conn.main)");
			}
			
			isTrace = JSonConfigReader.getIsTrace(json);
			this.withTrans = JSonConfigReader.getWithTran(json);
			
			sqlParser = null;
			String sysdb = JSonConfigReader.getdbid(json, "sys");
			if (StringUtil.stringIsNotEmpty(sysdb))
			{		
				sysOperator = ScriptObjectFactory.getDBOperator(sysdb);
				sqlParser = new SQLParser();
				sqlParser.checkInitialize(sysdb);
				sqlParser.setDefaultVer(JSonConfigReader.getVersion(json));
			}
			
			
			keyStream = null;
			if (this.jsonStream.hasStream())
			{
				keyStream = KeyStreamCoder.decodeFromByte(this.jsonStream.getStream());
			}else
			{
				keyStream = new KeyStream();
			}
			resultKeyStream = new KeyStream();
			dbOperator = ScriptObjectFactory.getDBOperator(key);		
			try
			{	
				this.doDBAction();		
			}finally
			{		
				dbOperator.close();			
				if (resultKeyStream.hasStream())
				{
					logger.info("回写KeyStream类型");
					this.jsonStream.setResultStreamType(1);//
					this.jsonStream.setStream(KeyStreamCoder.encode2Byte(resultKeyStream));
				}
			}
		}finally
		{
			dbOperator = null;
			sqlParser = null;
			sysOperator = null;
			json = null;
		}

	}

		
}
